/*
 * @Copyright: 2017 www.yyfax.com Inc. All rights reserved.
 */
package com.yyfax.pay.common.model.to;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yyfax.commons.lang.Md5Util;
import com.yyfax.framework.exception.YYRuntimeException;
import com.yyfax.framework.model.Params;
import com.yyfax.framework.yyfax.enums.ModuleEnum;
import com.yyfax.framework.yyfax.enums.RspCodeEnum;

/**
 * 支付模块请求包封装
 * 
 * @author jiangmy
 * @date 2017-04-11 13:57:54
 * @since v1.0.0
 */
@SuppressWarnings("serial")
public class YYPayReq<P extends Params> implements Serializable, Signable {

	private static final String MKEY_NAME = "_mkey";

	protected Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 模块ID
	 */
	private String mid;

	/**
	 * 签名参数,用于YYPayReq本身和Params里面的参数合起来按前面算法签名后的结果.
	 */
	private String sign;

	/**
	 * 参数列表
	 */
	private P params;

	public String getMid() {
		return mid;
	}

	public void setMid(String mid) {
		this.mid = mid;
	}

	public String getSign() {
		return sign;
	}

	public void setSign(String sign) {
		this.sign = sign;
	}

	public P getParams() {
		return params;
	}

	public void setParams(P params) {
		this.params = params;
	}

	public boolean validate() throws Exception {
		return this.params.validate();
	}

	public boolean checkSign() {
		return StringUtils.equals(this.sign, sign());
	}

	@Override
	@JsonIgnore
	public String sign() {
		List<String> list = new ArrayList<String>();
		Map<String, String> paramsMap = com.yyfax.commons.lang.BeanUtil.toMap(params);
		for (Entry<String, String> param : paramsMap.entrySet()) {
			if (StringUtils.isBlank(param.getKey()) || StringUtils.isBlank(param.getValue())) {
				continue;
			}
			list.add(param.getKey().concat("=").concat(param.getValue()));
		}
		// 加入模块密钥
		ModuleEnum module = ModuleEnum.fromValue(mid);
		if (module == null) {
			throw new YYRuntimeException(RspCodeEnum.COMMON_ERROR_NO_SIGN_AUTHENTICATION, "模块ID不正确");
		}
		list.add(MKEY_NAME.concat("=").concat(module.getMkey()));
		Collections.sort(list);
		String queryStr = StringUtils.join(list, "&");
		String sign = Md5Util.md5(queryStr);
		logger.debug("{} src:{} sign:{} verify:{}", params.getClass().getSimpleName(), queryStr, sign, this.sign);
		return sign;
	}

}
